package com.sjft.cloud.extension.generate.engine;

import com.sjft.cloud.extension.generate.config.CustomGlobalConfig;
import com.sjft.cloud.extension.generate.constant.CustomConstVal;
import com.sjft.cloud.extension.generate.bean.CustomTableInfo;
import com.sjft.cloud.extension.generate.properties.OutFileConfigProperties;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.ConstVal;
import com.baomidou.mybatisplus.generator.config.FileOutConfig;
import com.baomidou.mybatisplus.generator.config.TemplateConfig;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.FileType;
import com.baomidou.mybatisplus.generator.engine.AbstractTemplateEngine;
import com.baomidou.mybatisplus.generator.engine.VelocityTemplateEngine;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.util.List;
import java.util.Map;

/**
 * 自定义模板引擎配置
 *
 * @author Jin
 */
@Slf4j
public class CustomVelocityTemplateEngine extends VelocityTemplateEngine {

    @Override
    public AbstractTemplateEngine mkdirs() {
        getConfigBuilder().getPathInfo().forEach((key, value) -> {
            File dir = new File(value);
            if (!dir.exists()) {
                boolean result = dir.mkdirs();
                if (result) {
                    logger.debug("创建目录： [" + value + "]");
                }
            }
        });
        return this;
    }


    @Override
    public AbstractTemplateEngine batchOutput() {
        List<TableInfo> tableInfoList = getConfigBuilder().getTableInfoList();

        CustomGlobalConfig globalConfig = (CustomGlobalConfig) getConfigBuilder().getGlobalConfig();
        OutFileConfigProperties outFileConfigProperties = globalConfig.getOutFileConfigProperties();

        for (TableInfo tableInfo : tableInfoList) {
            Map<String, Object> objectMap = getObjectMap(tableInfo);
            Map<String, String> pathInfo = getConfigBuilder().getPathInfo();
            String entityName = tableInfo.getEntityName();
            TemplateConfig template = getConfigBuilder().getTemplate();

            //强转为扩展后的TableInfo
            CustomTableInfo customTableInfo = (CustomTableInfo) tableInfo;
            try {
                // 自定义内容
                InjectionConfig injectionConfig = getConfigBuilder().getInjectionConfig();
                if (null != injectionConfig) {
                    injectionConfig.initTableMap(tableInfo);
                    objectMap.put("cfg", injectionConfig.getMap());
                    List<FileOutConfig> focList = injectionConfig.getFileOutConfigList();
                    if (CollectionUtils.isNotEmpty(focList)) {
                        for (FileOutConfig foc : focList) {
                            if (isCreate(FileType.OTHER, foc.outputFile(tableInfo))) {
                                writerFile(objectMap, foc.getTemplatePath(), foc.outputFile(tableInfo));
                            }
                        }
                    }
                }

                if (outFileConfigProperties.getIncludeEntityFile() && null != entityName && null != pathInfo.get(ConstVal.ENTITY_PATH)) {
                    String entityFile = String.format((pathInfo.get(ConstVal.ENTITY_PATH) + File.separator + "%s" + suffixJavaOrKt()), entityName);
                    if (isCreate(FileType.ENTITY, entityFile)) {
                        writerFile(objectMap, templateFilePath(template.getEntity(getConfigBuilder().getGlobalConfig().isKotlin())), entityFile);
                    }
                }

                // MpMapper.java
                if (outFileConfigProperties.getIncludeMapperFile() && null != tableInfo.getMapperName() && null != pathInfo.get(ConstVal.MAPPER_PATH)) {
                    String mapperFile = String.format((pathInfo.get(ConstVal.MAPPER_PATH) + File.separator + tableInfo.getMapperName() + suffixJavaOrKt()), entityName);
                    if (isCreate(FileType.MAPPER, mapperFile)) {
                        writerFile(objectMap, templateFilePath(template.getMapper()), mapperFile);
                    }
                }
                // MpMapper.xml
                if (outFileConfigProperties.getIncludeMapperFile() && null != tableInfo.getXmlName() && null != pathInfo.get(ConstVal.XML_PATH)) {
                    String xmlFile = String.format((pathInfo.get(ConstVal.XML_PATH) + File.separator + tableInfo.getXmlName() + ConstVal.XML_SUFFIX), entityName);
                    if (isCreate(FileType.XML, xmlFile)) {
                        writerFile(objectMap, templateFilePath(template.getXml()), xmlFile);
                    }
                }
                // IMpService.java
                if (outFileConfigProperties.getIncludeServiceFile() && null != tableInfo.getServiceName() && null != pathInfo.get(ConstVal.SERVICE_PATH)) {
                    String serviceFile = String.format((pathInfo.get(ConstVal.SERVICE_PATH) + File.separator + tableInfo.getServiceName() + suffixJavaOrKt()), entityName);
                    if (isCreate(FileType.SERVICE, serviceFile)) {
                        writerFile(objectMap, templateFilePath(template.getService()), serviceFile);
                    }
                }
                // MpServiceImpl.java
                if (outFileConfigProperties.getIncludeServiceFile() && null != tableInfo.getServiceImplName() && null != pathInfo.get(ConstVal.SERVICE_IMPL_PATH)) {
                    String implFile = String.format((pathInfo.get(ConstVal.SERVICE_IMPL_PATH) + File.separator + tableInfo.getServiceImplName() + suffixJavaOrKt()), entityName);
                    if (isCreate(FileType.SERVICE_IMPL, implFile)) {
                        writerFile(objectMap, templateFilePath(template.getServiceImpl()), implFile);
                    }
                }
                // MpController.java
                if (outFileConfigProperties.getIncludeControllerFile() && null != tableInfo.getControllerName() && null != pathInfo.get(ConstVal.CONTROLLER_PATH)) {
                    String controllerFile = String.format((pathInfo.get(ConstVal.CONTROLLER_PATH) + File.separator + tableInfo.getControllerName() + suffixJavaOrKt()), entityName);
                    if (isCreate(FileType.CONTROLLER, controllerFile)) {
                        writerFile(objectMap, templateFilePath(template.getController()), controllerFile);
                    }
                }

                //生成DTO类文件
                if (outFileConfigProperties.getIncludeDtoFile() && null != customTableInfo.getInputDtoName() && null != pathInfo.get(CustomConstVal.DTO_PATH)) {
                    String inputDTOFile = String.format((pathInfo.get(CustomConstVal.DTO_PATH) + File.separator + customTableInfo.getInputDtoName() + suffixJavaOrKt()), entityName);
                    if (isCreate(FileType.OTHER, inputDTOFile)) {

                        writer(objectMap, templateFilePath(CustomConstVal.TEMPLATE_INPUT_DTO), inputDTOFile);

                    }
                }
                if (outFileConfigProperties.getIncludeDtoFile() && null != customTableInfo.getUpdateDtoName() && null != pathInfo.get(CustomConstVal.DTO_PATH)) {
                    String updateDTOFile = String.format((pathInfo.get(CustomConstVal.DTO_PATH) + File.separator + customTableInfo.getUpdateDtoName() + suffixJavaOrKt()), entityName);
                    if (isCreate(FileType.OTHER, updateDTOFile)) {
                        writer(objectMap, templateFilePath(CustomConstVal.TEMPLATE_UPDATE_DTO), updateDTOFile);
                    }
                }
                if (outFileConfigProperties.getIncludeDtoFile() && null != customTableInfo.getQueryDtoName() && null != pathInfo.get(CustomConstVal.DTO_PATH)) {
                    String queryDTOFile = String.format((pathInfo.get(CustomConstVal.DTO_PATH) + File.separator + customTableInfo.getQueryDtoName() + suffixJavaOrKt()), entityName);
                    if (isCreate(FileType.OTHER, queryDTOFile)) {
                        writer(objectMap, templateFilePath(CustomConstVal.TEMPLATE_QUERY_DTO), queryDTOFile);
                    }
                }

                //生成VO类文件
                if (outFileConfigProperties.getIncludeVoFile() && null != customTableInfo.getEntityVoName() && null != pathInfo.get(CustomConstVal.VO_PATH)) {
                    String voFile = String.format((pathInfo.get(CustomConstVal.VO_PATH) + File.separator + customTableInfo.getEntityVoName() + suffixJavaOrKt()), entityName);
                    if (isCreate(FileType.OTHER, voFile)) {
                        writer(objectMap, templateFilePath(CustomConstVal.TEMPLATE_VO), voFile);
                    }
                }

                //生成Wrapper包装类文件
                if (outFileConfigProperties.getIncludeWrapperFile() && null != customTableInfo.getWrapperName() && null != pathInfo.get(CustomConstVal.WRAPPER_PATH)) {
                    String wrapperFile = String.format((pathInfo.get(CustomConstVal.WRAPPER_PATH) + File.separator + customTableInfo.getWrapperName() + suffixJavaOrKt()), entityName);
                    if (isCreate(FileType.OTHER, wrapperFile)) {
                        writer(objectMap, templateFilePath(CustomConstVal.TEMPLATE_WRAPPER), wrapperFile);
                    }
                }

                //生成Feign接口类文件
                if (outFileConfigProperties.getIncludeFeignFile() && null != customTableInfo.getFeignName() && null != pathInfo.get(CustomConstVal.FEIGN_PATH)) {
                    String feignFile = String.format((pathInfo.get(CustomConstVal.FEIGN_PATH) + File.separator + customTableInfo.getFeignName() + suffixJavaOrKt()), entityName);
                    if (isCreate(FileType.OTHER, feignFile)) {
                        writer(objectMap, templateFilePath(CustomConstVal.TEMPLATE_FEIGN), feignFile);
                    }
                }

                //生成Feign实现类文件
                if (outFileConfigProperties.getIncludeFeignFile() && null != customTableInfo.getFeignFallBackName() && null != pathInfo.get(CustomConstVal.FEIGN_FALLBACK_PATH)) {
                    String feignFeignFallbackFile = String.format((pathInfo.get(CustomConstVal.FEIGN_FALLBACK_PATH) + File.separator + customTableInfo.getFeignFallBackName() + suffixJavaOrKt()), entityName);
                    if (isCreate(FileType.OTHER, feignFeignFallbackFile)) {
                        writer(objectMap, templateFilePath(CustomConstVal.TEMPLATE_FEIGN_FALLBACK), feignFeignFallbackFile);
                    }
                }

            } catch (Exception e) {
                log.error("代码生成出错！- {}", e.getMessage());
            }

        }
        return this;
    }
}
